home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGNG_C / DBTOOLC.LZH / SOURCE.ARC / DBFIN.C < prev    next >
C/C++ Source or Header  |  1986-06-30  |  10KB  |  347 lines

  1.  
  2. /* 
  3. *   NAME:
  4. *       finance.c
  5. *   
  6. * SYNOPSIS:
  7. *   fv(pmt, rate, term) -- future value function
  8. *   pv(pmt, rate, term) -- present value function   
  9. *   npv(pmt, flows, n)  -- net present value function
  10. *   pmt(prin, rate, term)   -- amortized payment function
  11. *   amort(prin, rate, n1, n2) -- amortization function
  12. *   sf(amt, rate, n)    -- sinking fund function
  13. *   irr(guess, flows, n)    -- internal rate of return
  14. *   mirr(risky, safe, flows, n) -- modified irr
  15. *
  16. *   DESCRIPTION:
  17. *   'Low level' financial functions for dBASE library. All are
  18. *   called by a jacketed routine from the main program pak.
  19. *   
  20. *   RETURNS:
  21. *   All functions return the actual result of the calculation as
  22. *   a double precision floating point value.
  23. *
  24. *   AUTHOR: J. T. Cooper    
  25. */
  26.  
  27. #include <stdio.h>
  28. #ifdef AZTEC
  29. #include "math.h"
  30. double atof();
  31. double atol();
  32. #else
  33. #include <dos.h>
  34. #include <math.h>
  35. #endif
  36.  
  37.  
  38. /* 
  39. *   NAME:   fv - future value function
  40. *
  41. *   SYNOPSIS:
  42. *   double fv(pmt, rate, term)
  43. *   double pmt; -- regular, periodic payment amount
  44. *   double rate;    -- interest rate per period
  45. *   int term;   -- number of periods
  46. *
  47. *   DESCRIPTION:
  48. *   Calculates future (compounded) value of an annuity (ie,
  49. *   equal, regular payments) at a set interest rate for a 
  50. *   given number of periods, according to the following formula:
  51. *
  52. *                     pmt * ((1 + rate)^term - 1)
  53. *       fv(pmt, rate, term) = ---------------------------
  54. *                       rate
  55. *   
  56. *   RETURNS:
  57. *   Returns the future value.
  58. */
  59.  
  60. double fv(pmt, rate, term)
  61. double pmt, rate;
  62. int term;
  63. {
  64.     return(pmt * (pow(1.0 + rate, (double)term) - 1.0)/rate);
  65. }
  66.  
  67.  
  68. /* 
  69. *   NAME:
  70. *   pv - present value function
  71. *
  72. *   SYNOPSIS:
  73. *   double pv(pmt, rate, term)
  74. *   double pmt; -- amount of regular payment (deposit)
  75. *   double rate;    -- interest rate per period
  76. *   int term;   -- number of periods
  77. *
  78. *   DESCRIPTION:
  79. *   Calculates present value of an annuity at a set interest
  80. *   rate for the given number of periods, using the formula:
  81. *
  82. *                     pmt * (1 - 1/((1+rate)^term))
  83. *       pv(pmt, rate, term) = ------------------------------
  84. *                       rate
  85. *
  86. *   RETURNS:
  87. *   Returns the present value as a double precision floating
  88. *   point variable.
  89. *
  90. */
  91.  
  92. double pv(pmt, rate, term)
  93. double pmt, rate;
  94. int term;
  95. {
  96.     return(pmt * ((1.0 - pow(1.0 + rate, (double)(-term)))/rate));
  97. }
  98.  
  99.  
  100. /* 
  101. *   NAME:
  102. *   npv - net present value function
  103. *
  104. *   SYNOPSIS:
  105. *   double npv(rate, flows, n)
  106. *   double  rate;   -- interest rate per period
  107. *   double  flows[]; -- list (array) of cash flows
  108. *   int n;  -- # of payments to expect
  109. *
  110. *   DESCRIPTION:
  111. *   Using the given discount rate, npv sums the present
  112. *   value of the cash flows; ie,
  113. *
  114. *   npv(rate,flows,n) = sum of all (flows[i]/(1+rate)^i)
  115. *       where i ranges from 0 to n.
  116. *               
  117. *   RETURNS:
  118. *   Returns the net present value of the cash flows as a
  119. *   double precision floating point variable.
  120. *
  121. */
  122.  
  123. double npv(rate, flows, n)
  124. double rate;    /* interest rate per period */
  125. double flows[]; /* array of double precision variables */
  126. int n;      /* # of payments to expect */
  127. {
  128. double result;
  129.  
  130.     result = 0.0;
  131.     while (n--)
  132.         result += flows[n]/pow(1.0 + rate, (double)n);
  133.     return(result);
  134. }
  135.  
  136.  
  137. /* 
  138. *   NAME:
  139. *       pmt - calculate amortized payment
  140. *
  141. *   SYNOPSIS:
  142. *   double(prin, rate, term)
  143. *   double prin;    -- principal balance of a loan
  144. *   double rate;    -- interest per period
  145. *   int term;   -- number of periods
  146. *
  147. *   DESCRIPTION:
  148. *   Calculates the constant, regular payments (made at the end
  149. *   of each period) needed to fully pay off a loan of the given
  150. *   amount (prin), rate, and term:
  151. *                           rate
  152. *       pmt(prin, rate, term) = prin * --------------------
  153. *                       1 - 1/(1+rate)^term
  154. *   RETURNS:
  155. *   Returns the payment amount as a double precision floating
  156. *   point number.
  157. *   
  158. */
  159.  
  160. double pmt(prin, rate, term)
  161. double prin;    /* principal balance of a loan */
  162. double rate;    /* interest rate per pmt (!= 0) */
  163. int term;   /* number of periods */
  164. {
  165.     return(prin / ((1.0 - pow(1.0 + rate, (double)(-term)))/rate));
  166. }
  167.  
  168.  
  169. /* 
  170. *   NAME:
  171. *   amort - amortization function
  172. *
  173. *   SYNOPSIS:
  174. *   double amort(prin, rate, n1, n2)
  175. *   double  prin;   -- principal amount of loan
  176. *   double  rate;   -- interest rate per period
  177. *   int n1; -- total number of periods
  178. *   int n2; -- number of payments completed
  179. *
  180. *   DESCRIPTION:
  181. *   Calculates the amount of loan principal still outstanding
  182. *   after a given number of payments:
  183. *
  184. *                        1 - 1/(1+rate)^(n1-n2)
  185. *       amort(prin,rate,n1, n2) = prin * ----------------------
  186. *                        1 - 1/(1+rate)^n1
  187. *   RETURNS:
  188. *   Returns the amortized amount as a double precision floating
  189. *   point variable.
  190. *   
  191. */
  192.  
  193. double amort(prin, rate, n1, n2)
  194. double  prin,   /* principal */
  195.     rate;   /* interest rate per period */
  196. int n1, /* total # of periods */
  197.     n2; /* payments completed */
  198. {
  199.  
  200.     return(prin * ((1.0 - (1.0/(pow(1.0 + rate, (double)(n1 - n2))))) /
  201.         (1.0 - (1.0/(pow(1.0 + rate, (double) n1))))));
  202. }
  203.  
  204.  
  205. /* 
  206. *   NAME:
  207. *   sf - sinking fund function
  208. *
  209. *   SYNOPSIS:
  210. *   double sf(amt, rate, n)
  211. *   double amt; -- amount to be accumulated
  212. *   double rate;    -- interest rate per period
  213. *   int n;  -- total number of deposits to be made
  214. *
  215. *   DESCRIPTION:
  216. *   Calculates the deposit required at the end of each period
  217. *   which would be necessary to accumulate a given amount, 
  218. *   assuming a given interest rate and term:
  219. *                        rate
  220. *       sf(amt, rate, n) = amt * --------------
  221. *                    (1+rate)^n - 1
  222. *   
  223. *   RETURNS:
  224. *   Returns the deposit amount as a double precision floating
  225. *   point number.
  226. */
  227.  
  228. double sf(amt, rate, n)
  229. double  amt,    /* amount to be accumulated */
  230.     rate;   /* interest rate per period */
  231. int n;  /* total # of deposits */
  232. {
  233.     return(amt * (rate / (pow(1.0 + rate, (double) n) - 1.0)));
  234. }
  235.  
  236.  
  237. /* 
  238. *   NAME:
  239. *   irr - internal rate of return function
  240. *
  241. *   SYNOPSIS:
  242. *   double irr(guess, flows, n)
  243. *   double guess;   -- initial guess
  244. *   double flows[]; -- list (array) of cash flows
  245. *   int n;  -- total number of periods
  246. *
  247. *   DESCRIPTION:
  248. *   Approximates the interest rate which equates the present
  249. *   value of cash outflows and inflows; ie, the rate at which
  250. *   the present value of flows would be 0. Uses a home-brew
  251. *   algorithm which converges on a result using the initial guess
  252. *   as a starting point, and which seems to come reasonably 
  253. *   close to those values obtained by Framework. 
  254. *   
  255. *   RETURNS:
  256. *   Returns the net present value of flows as a double precision
  257. *   floating point number.
  258. *   
  259. *   NOTES:
  260. *   No confirmation of the algorithm used could be found; rather,
  261. *   empirical data has been used to establish its soundness.
  262. *
  263. */
  264. double irr(guess, flows, n)
  265. double guess;   /* initial guess */
  266. double flows[]; /* array of double precision variables */
  267. int n;      /* # of periods to expect */
  268. {
  269. double  zero;   /* solution should approach 0.00 */
  270. double  high, low;  /* will converge using these limits */
  271. int cnt = 0;
  272. int i;
  273. int p;
  274. double  div;
  275. #define MAXIRRITER  30  /* Max # of iterations */
  276.  
  277.     high = (guess > 0 ? guess + 1.0 : 1.0);
  278.     low = (guess <= 1 ? guess -1.0 : 0.0);
  279.     do
  280.     {
  281.         i = n;
  282.         zero = 0.0;
  283.         while (i--)
  284.         {
  285.             div = 1.0;
  286.             for (p = i; p; p--)
  287.                 div *= (1.0 + guess);
  288.             zero += flows[i]/div;
  289.         }
  290.         if (zero > 0.0)
  291.         low = guess;
  292.         else
  293.         high = guess;
  294.         guess = (high - low)/2.0 + low;
  295.         ++ cnt;
  296.     } while (cnt < MAXIRRITER && zero != 0.0);
  297.                 /* (zero == EACTLY 0.0 is unlikely) */
  298.     return(guess);
  299. }
  300.  
  301.  
  302. /* 
  303. *   NAME:
  304. *   mirr - modified internal rate of return
  305. *
  306. *   SYNOPSIS:
  307. *   double mirr(r, s, flows, n)
  308. *   double r;   -- 'risky' rate at which outlays are financed
  309. *   double s;   -- 'safe' rate at which revenues are invested
  310. *   double flows[]; -- list (array) of cash flows
  311. *   int n;  -- total number of cash flows
  312. *
  313. *   DESCRIPTION:
  314. *   Calculates the rate of return for an investment given the
  315. *   rate of return for future positive cash flows and the rate
  316. *   at which future cash outlays are to be discounted:
  317. *
  318. *                 npv(r, positive flows)(1+r)^n
  319. *   mirr(r,s,flows,n) = { ----------------------------- }^(1/n) - 1
  320. *                 -npv(s, negative flows)
  321. *   RETURNS:
  322. *   Returns the modified internal rate of return as a double 
  323. *   precision floating point number.
  324. *   
  325. */
  326.  
  327. double mirr(r, s, flows, n)
  328. double  r;  /* 'risky' rate at which outlays are financed */
  329. double  s;  /* 'safe' rate at which revenues are invested */
  330. double  flows[];    /* list of cash flows */
  331. int n;  /* # of cash flows */
  332. {
  333. double  npvneg = 0.0;   /* net present value of negative cash flows */
  334. double  npvpos = 0.0;   /* npv of positive cash flows */
  335. int i;
  336.  
  337.     for (i = 0; i < n; i++)
  338.     {
  339.         if (flows[i] > 0)
  340.          npvpos += flows[i]/pow(1.0 + r, (double)i);
  341.         else
  342.          npvneg += flows[i]/pow(1.0 + s, (double)i);
  343.     }
  344.     return( pow((npvpos * pow((1.0+r),(double)(n-1))) / -npvneg, 
  345.         1.0/(double)(n-1)) - 1.0);
  346. }
  347.